home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / daemons / nfs / nfs-serv.2be / nfs-serv / nfs-server-2.2beta16 / rquotad.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-06  |  4.0 KB  |  203 lines

  1. /*
  2.  * rquotad    Authenticate rquota requests and retrieve file handle.
  3.  *
  4.  * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
  5.  */
  6.  
  7. #include <signal.h>
  8. #include <sys/stat.h>
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11. #include <sys/vfs.h>
  12. #include <stdio.h>
  13. #include <paths.h>
  14. #include <mntent.h>
  15. #include "rquotad.h"
  16. #include "logging.h"
  17. #include "rpcmisc.h"
  18.  
  19. #ifndef _PATH_MTAB
  20. #define _PATH_MTAB    "/etc/mtab"
  21. #endif
  22.  
  23. #ifdef HAVE_QUOTACTL
  24. static char *    getdevice(char *path);
  25. #endif
  26. static void    usage(int exitcode);
  27.  
  28. static struct option longopts[] =
  29. {
  30.     { "foreground", 0, 0, 'F' },
  31.     { "debug", 1, 0, 'd' },
  32.     { "help", 0, 0, 'h' },
  33.     { "version", 0, 0, 'v' },
  34.     { NULL, 0, 0, 0 }
  35. };
  36.  
  37. bool_t
  38. rquota_null_1_svc(struct svc_req *rqstp, void *argp, void *resp)
  39. {
  40.     return 1;
  41. }
  42.  
  43. #ifdef HAVE_QUOTACTL
  44. bool_t
  45. rquota_getquota_1_svc(struct svc_req *rqstp, getquota_args *argp,
  46.                          getquota_rslt *resp)
  47. {
  48.     struct sockaddr_in *sin = svc_getcaller(rqstp->rq_xprt);
  49.     char        *special;
  50.     struct dqblk    qtinfo;
  51.     struct statfs    fsinfo;
  52.     struct rquota    rqot;
  53.     uid_t        uid = (uid_t) argp->gqa_uid;
  54.  
  55.     /* The rquota.x file suggests that AUTH_UNIX be required;
  56.      * but since UNIX credentials can't be trusted much anyway,
  57.      * we use simple port checking.
  58.      */
  59.     if (ntohs(sin->sin_port) >= IPPORT_RESERVED) {
  60.         resp->status = Q_EPERM;
  61.         return 1;
  62.     }
  63.  
  64.     resp->status = Q_NOQUOTA;
  65.     if (!(special = getdevice(argp->gqa_pathp)))
  66.         return 1;
  67.  
  68.     if (statfs(argp->gqa_pathp, &fsinfo) < 0
  69.      || quotactl(QCMD(Q_GETQUOTA, USRQUOTA), special, uid, &qtinfo) < 0)
  70.         return 1;
  71.  
  72.     rqot = &resp->getquota_rslt_u.gqr_rquota;
  73.     rqot->status        = Q_OK;
  74.     rqot->rq_bsize        = fsinfo.f_bsize;
  75.     rqot->rq_active        = 1;        /* always active */
  76.     rqot->rq_bhardlimit = qtinfo.dqb_bhardlimit;
  77.     rqot->rq_bsoftlimit = qtinfo.dqb_bsoftlimit;
  78.     rqot->rq_curblocks  = qtinfo.dqb_curblocks;
  79.     rqot->rq_fhardlimit = qtinfo.dqb_fhardlimit;
  80.     rqot->rq_fsoftlimit = qtinfo.dqb_fsoftlimit;
  81.     rqot->rq_curfiles   = qtinfo.dqb_curfiles;
  82.     rqot->rq_btimeleft  = qtinfo.dqb_btimeleft;
  83.     rqot->rq_ftimeleft  = qtinfo.dqb_ftimeleft;
  84.  
  85.     return 1;
  86. }
  87. #else
  88. bool_t
  89. rquota_getquota_1_svc(struct svc_req *rqstp, getquota_args *argp,
  90.                          getquota_rslt *resp)
  91. {
  92.     resp->status = Q_NOQUOTA;
  93.     return 1;
  94. }
  95. #endif
  96.  
  97. bool_t
  98. rquota_getactivequota_1_svc(struct svc_req *rqstp, getquota_args *argp,
  99.                            getquota_rslt *resp)
  100. {
  101.     /* What's the difference between these two? */
  102.     return rquota_getquota_1_svc(rqstp, argp, resp);
  103. }
  104.  
  105. int
  106. main(int argc, char **argv)
  107. {
  108.     int    foreground = 0;
  109.     int    c;
  110.  
  111.     rpc_init("rquotad", RQUOTAPROG, RQUOTAVERS, rquota_dispatch, 0, 0);
  112.  
  113.     /* Parse the command line options and arguments. */
  114.     opterr = 0;
  115.     while ((c = getopt_long(argc, argv, "Fd:hv", longopts, NULL)) != EOF) {
  116.         switch (c) {
  117.         case 'F':
  118.             foreground = 1;
  119.             break;
  120.         case 'd':
  121.             enable_logging(optarg);
  122.             break;
  123.         case 'h':
  124.             usage(0);
  125.             break;
  126.         case 'v':
  127.             printf("rquotad %s\n", VERSION);
  128.             exit(0);
  129.         case 0:
  130.             break;
  131.         case '?':
  132.         default:
  133.             usage(1);
  134.         }
  135.     }
  136.  
  137.     /* No more arguments allowed. */
  138.     if (optind != argc)
  139.         usage(1);
  140.  
  141.     if (!foreground) {
  142.         /* We first fork off a child. */
  143.         if ((c = fork()) > 0)
  144.             exit(0);
  145.         if (c < 0) {
  146.             dprintf(L_FATAL, "rquotad: cannot fork: %s\n",
  147.                         strerror(errno));
  148.         }
  149.         /* Now we remove ourselves from the foreground. */
  150.         close(0);
  151.         close(1);
  152.         close(2);
  153.         setsid();
  154.     }
  155.  
  156.     /* Initialize logging. */
  157.     log_open("rquotad", foreground);
  158.  
  159.     svc_run();
  160.  
  161.     dprintf(L_ERROR, "Ack! Gack! svc_run returned!\n");
  162.     exit(1);
  163. }
  164.  
  165. #ifdef HAVE_QUOTACTL
  166. static char *
  167. getdevice(char *path)
  168. {
  169.     static char    special[PATH_MAX];
  170.     struct mntent    *mnt;
  171.     FILE        *fp;
  172.     int        mlen, plen;
  173.  
  174.     if (!(fp = setmntent(_PATH_MTAB, "r")))
  175.         return NULL;
  176.     
  177.     special[0] = '\0';
  178.     mlen = 0;
  179.     while ((mnt = getmntent(fp)) != NULL) {
  180.         plen = strlen(mnt->mnt_dir);
  181.         if (!strncmp(mnt->mnt_dir, path, plen) && plen > mlen) {
  182.             strcpy(special, mnt->mnt_dir);
  183.             mlen = plen;
  184.         }
  185.         if (path[plen] == '\0')
  186.             break;
  187.     }
  188.  
  189.     endmntent(fp);
  190.  
  191.     return mlen? special : NULL;
  192. }
  193. #endif
  194.  
  195. static void
  196. usage(int n)
  197. {
  198.     fprintf(stderr,
  199.         "Usage: rpc.rquotad [-Fhnpv] [-d kind]\n"
  200.         "       [--debug kind] [--help] [--version]\n");
  201.     exit(n);
  202. }
  203.